package binbaum;

import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
import javax.swing.JPanel;

public class BaumPanel extends JPanel{
  protected IBinKnoten hohlkopf;
  protected double rx,ry,dx2,dy;
  protected RectangularShape form;
  protected Font font;

  public BaumPanel(double rx, double ry, double dx, double dy, boolean rund){
    this.rx=rx; this.ry=ry; dx2=dx/2; this.dy=dy;
    form=rund?new Ellipse2D.Double():new Rectangle2D.Double();
    font=new Font("SansSerif", Font.PLAIN, (int)(2*ry));
    setOpaque(false);
  }

  public BaumPanel(){
    this(10, 10, 5, 5, true);
  }

  public void setPseudoWurzel(IBinKnoten n){
    hohlkopf=n;
    repaint();
  }

  public void setDist(double dx, double dy){
    dx2=dx/2;
    this.dy=dy;
    repaint();
  }

  @Override
  public void paintComponent(Graphics g){
    Graphics2D g2=(Graphics2D)g;
    g2.setFont(font);
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    clip=g2.getClip();
    drawTreeFrom(hohlkopf.rson(), 0, g2, 0, true);
    setPreferredSize(size);
  }

  protected Dimension size=new Dimension();
  protected Line2D.Double kante=new Line2D.Double();
  protected Shape clip;
  /* Zeichnet den BinBaum vom IBinKnoten ab aus. x gibt den aktuellen
   * linken Rand an. grave=true bedeutet, dass es ein rechter IBinKnoten wird.
   */
  protected double drawTreeFrom(IBinKnoten ab, int ebene, Graphics2D g2,
                                double x, boolean grave){
    if(ab==null || ab.rson()==ab) return rx;
    double lwid=drawTreeFrom(ab.lson(), ebene+1, g2, x, false);
    x+=lwid;
    double rwid=drawTreeFrom(ab.rson(), ebene+1, g2, x+dx2, true);
    double y=(2*ry+dy)*ebene+ry;
    if(ebene>0){
      kante.setLine(x,y,x+(grave?-lwid-dx2:rwid+dx2),y-2*ry-dy);
      g2.draw(kante);
    }
    form.setFrameFromCenter(x, y, x+rx, y+ry);
    size.setSize(Math.max(size.getWidth(),x+rx), Math.max(size.getHeight(),y+ry));
    g2.setColor(Color.white);
    g2.fill(form);
    g2.setColor(Color.black);
    g2.draw(form);
    // schreibe IBinKnoten
    g2.clip(form);
    String t=ab.datum()+"";
    Rectangle2D r=font.getStringBounds(t, g2.getFontRenderContext());
    double b=r.getWidth()/2;
    if(b>rx) b=rx;
    g2.drawString(t, (float)(x-b), (float)(y+.75*ry));
    g2.setClip(clip);
    // Rückgabe der ganzen Breite und eines halben Abstands
    return lwid+rwid+dx2;//dieses dx2 links bzw. rechts dazugedacht
  }
}
